package com.coscon.config;


import cn.hutool.core.net.NetUtil;
import cn.hutool.system.SystemUtil;
import com.coscon.service.ConfigService;
import com.coscon.service.CoreAuthService;
import com.coscon.service.DbInitService;
import com.coscon.service.FtpService;
import com.coscon.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ftpserver.ftplet.FtpException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.security.SecureRandom;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Random;

/**
 * @Description: 当项目启动后，执行初始化
 * @Author: 409390047@qq.com
 * @Date: 2021/6/16 10:13
 */
@Slf4j
@Component
public class ApplicationStartup implements ApplicationRunner {

    //
    private boolean rebootAuthCheck = false;
    @Value("${server.port:8888}")
    private Integer serverPort = null;

    @Resource
    private DbInitService dbInitService;//数据库初始化

    @Resource
    private CoreAuthService coreAuthService;

    @Resource
    private ConfigService configService;
    @Resource
    private FtpService ftpService;

    //认证的验证码
    private String authCode;

    private SecureRandom ran;

    ApplicationStartup(){
        ran = new SecureRandom();
    }

    @Override
    public void run(ApplicationArguments applicationArguments)  {
        log.debug("------------项目启动时初始化动作----------------------");

        //执行数据库初始化
        this.dbInitService.initSystemTables();


        //1：打印命令
        printCurPid();
        //2:当spring ， 容器完成后，测试下robot，如果有问题，就抛出异常，在mac下，如果没有权限，则弹出配置界面
        try {
            testRobot();
            rebootAuthCheck = true;//标记robot权限检测通过
        } catch (AWTException e) {
            rebootAuthCheck = false;//标记robot权限检测未通过
            log.warn(e.getMessage());
        }


        //其他需要初始化的，在此.....
        try {
            ftpService.initFtpServer();
        } catch (FtpException e) {
            e.printStackTrace();
        }

        //根据配置，重新加载shiro规则
        coreAuthService.reloadApacheShiroAuthFilterChains();

        //打印访问地址
        printLoaclIpInfo();

        //打印认证码
        printAuthCode();

    }


    private void printCurPid(){
        log.debug("------------获取当前进程的PID----------------------");
        String name = ManagementFactory.getRuntimeMXBean().getName();
        log.debug("name=" + name);
        SystemUtil.dumpSystemInfo();
        RuntimeMXBean runtimeMxBean = SystemUtil.getRuntimeMXBean();
        log.debug("runtimeMXBean.getStartTime()=" + runtimeMxBean.getStartTime());
        long pid = SystemUtil.getCurrentPID();//StringUtils.substringBefore(name,"@");
        log.debug("PID=" + pid);
        String dateTimeStr =  DateUtils.getCurDateTime();
        log.debug("下载dump文件的命令是：jmap -dump:format=b,file=d:/heapdump_{} {}", dateTimeStr, pid);
        log.debug("查看dump文件的命令是：jhat -port 7001 d:/heapdump_{}", dateTimeStr);
    }

    /**
     * 当spring ， 容器完成后，测试下robot，如果有问题，就抛出异常，在mac下，如果没有权限，则弹出配置界面
     * @throws AWTException
     */
    private void testRobot() throws AWTException {
        Robot rb = new Robot();
        rb.keyPress(KeyEvent.VK_CONTROL);
        rb.delay(50);
        rb.keyRelease(KeyEvent.VK_CONTROL);
    }

    /**
     * 打印本机IP信息
     */
    private  void printLoaclIpInfo(){
        LinkedHashSet<String> listIp = NetUtil.localIps();
        log.debug("本机IP如下：");
        for(String ip : listIp){
            log.debug("ip:" + ip);
        }
        String url =getSystemViewHttpUrl();
        log.debug("访问地址：" + url);
    }


    public String getSystemViewHttpUrl(){
        String url = "http://" + SystemUtil.getHostInfo().getAddress()+":" + serverPort;
        return url;
    }

    /**
     * 打印输出，校验的验证码
     */
    public void printAuthCode(){
        Map<String, String> map = this.configService.getSysconfigValByKeys(
                "security_is_user"
                ,"security_password_type"
                ,"security_custom_password"
        );
        String security_is_user = map.get("security_is_user");
        String securityPasswordType = map.get("security_password_type");
        String securityCustomPassword = map.get("security_custom_password");
        if(!StringUtils.equalsIgnoreCase("on",security_is_user)){
            return;
        }
        if(StringUtils.isBlank(this.getAuthCode())){
            String code = null;
            if(StringUtils.equalsIgnoreCase(securityPasswordType,"2")){//自定义认证密码
                code = securityCustomPassword;
            }else{//每次启动随机产生（控制台查看）
                code = getRandomCode();
            }
            //如果采用自定义密码，并且没有配置自定义密码，则随机产生个
            if(org.apache.commons.lang3.StringUtils.isBlank(securityCustomPassword)){
                code = getRandomCode();
            }
            this.setAuthCode(code);
        }
        log.debug("认证验证码：" + this.getAuthCode());
        System.out.println("认证验证码：" + this.getAuthCode());
    }


    /**
     * 随机生成6位数字验证码
     * @return
     */
    public  String getRandomCode() {
        String phoneCode = String.valueOf(((int) (ran.nextDouble() * 1000000)));
        phoneCode = StringUtils.leftPad(phoneCode, 6, '0');
        return phoneCode;
    }


    public boolean isRebootAuthCheck() {
        return rebootAuthCheck;
    }

    public String getAuthCode() {
        return authCode;
    }

    public void setAuthCode(String authCode) {
        this.authCode = authCode;
    }

}